package BasicClient;

import java.util.HashMap;

public class ClientImpl extends AbstractClient {

	@Override
	public void setBlinds(int smallBlind, int bigBlind, int ante) {
		this.bigBlind = bigBlind;
		this.smallBlind = smallBlind;
		this.notifyObservers(EventType.BlindUpdate);
	}

	@Override
	public void setOrder(int tableID, int[] playerIDArray) {
		this.playerMap.clear();
		for(int i=0; i<playerIDArray.length; i++){
			PokerPlayer p = new PokerPlayer(i, stackSize);
			Integer pid = new Integer(playerIDArray[i]);
			this.playerMap.put(pid, p);			
		}
		this.notifyObservers(EventType.OrderUpdate);
	}

	@Override
	public void playerFold(int playerID) {
		this.playerMap.get(playerID).fold();
		this.notifyObservers(EventType.PlayerFold);
	}

	@Override
	public void playerCall(int playerID) {
		// need to determine the call amount, its not in the protocol
		// call amount = biggest amount on the table - clients amount on table
		
		// find biggest amount on table
		int biggestValue = 0;
		for(PokerPlayer p : this.playerMap.values()){
			if(biggestValue < p.getAmountInvestedInHand()){
				biggestValue = p.getAmountInvestedInHand();
			}
		}
		
		int clientsValue = this.playerMap.get(this.pID).getAmountInvestedInHand();
		int callAmount = biggestValue - clientsValue;
		
		this.playerMap.get(this.pID).decreaseStackSize(callAmount);
		this.playerMap.get(this.pID).addAmountInvestedInhand(callAmount);
		
		this.notifyObservers(EventType.PlayerCall);
	}

	@Override
	public void playerRaise(int playerID, int raise) {
		this.playerMap.get(playerID).decreaseStackSize(raise);
		this.playerMap.get(playerID).addAmountInvestedInhand(raise);
		
		this.notifyObservers(EventType.PlayerRaise);
	}

	@Override
	public void playerDisconnectReconnect(Status status, int playerID) {
		this.playerMap.get(playerID).setConnectedStatus(status);	
		this.notifyObservers(EventType.PlayerDiscConn);
	}

	@Override
	public void newGame(int tableSize, int numOfPlayers, int stackSize) {
		this.stackSize = stackSize;
		this.notifyObservers(EventType.NewGame);
	}

	@Override
	public void newHand(int buttonLocation, int handID, int tableID) {
		this.dealerButtonLocation = buttonLocation;
		this.handID = handID;
		this.tableID = tableID;
		this.tableCards.clear();
		this.holeCards.clear();
		
		for(PokerPlayer p : this.playerMap.values()){
			p.newHand();
		}
		this.notifyObservers(EventType.NewHand);
	}

	@Override
	public void handEnd(HashMap<Integer, Integer> winnerMap) {
		// end of hand, remove each players amount invested in the hand
		for(Integer pid : winnerMap.keySet()){
			this.playerMap.get(pid).increaseStackSize(winnerMap.get(pid));
		}
		this.notifyObservers(EventType.EndHand);
	}

	@Override
	public void flop(String[] cards) {
		for(int i=0; i<cards.length; i++){
			this.tableCards.add(cards[i]);
		}
		this.notifyObservers(EventType.Flop);
	}

	@Override
	public void turn(String card) {
		this.tableCards.add(card);
		this.notifyObservers(EventType.Turn);
	}

	@Override
	public void river(String card) {
		this.tableCards.add(card);
		this.notifyObservers(EventType.River);
	}

	@Override
	public void setHoleCards(String[] cards) {
		for(int i=0; i<cards.length; i++){
			this.holeCards.add(cards[i]);
		}
		this.notifyObservers(EventType.HoleCards);
	}

	@Override
	public void assignPlayerID(int playerID) {
		this.pID = playerID;
		System.out.println("Assigned player ID " + playerID);
	}

	@Override
	public void actionRequired(int toCallAmount) {
		this.notifyObservers(EventType.ActionRequired);		
	}
}
